<template>
  <div class="CB">
    <el-container class="chat-container-height">
      <el-main class="el-mai" ref="mainContainer">
        <ChatContent
          ref="weChatContent"
          @positionView="positionView"
          @reEdit="reEdit"
          @quoteMessage="handleQuoteMessage"
        />
      </el-main>

      <el-footer height="180px">
        <div v-show="groupChatStatus">
          <div class="chat-tool-bar">
            <div class="el-icon-eleme" @click="loadEmojis"></div>
            <div
              title="图片"
              slot="reference"
              class="el-icon-picture-outline"
              @click="showRecordBox()"
            ></div>
            <div
              title="视频"
              slot="reference"
              class="el-icon-film"
              @click="showRecordBox()"
            ></div>
            <div
              title="文件"
              slot="reference"
              class="el-icon-folder"
              @click="showRecordBox()"
            ></div>
            <div
              title="语音通话"
              slot="reference"
              class="el-icon-phone-outline"
              @click="showRecordBox()"
            ></div>
            <div
              title="视频通话"
              slot="reference"
              class="el-icon-video-camera"
              @click="showRecordBox()"
            ></div>
            <div
              title="语音消息"
              slot="reference"
              class="el-icon-microphone"
              @click="showRecordBox()"
            ></div>
          </div>
          <div class="send-content-area">
            <ChatEditor
              ref="chatEditor"
              :parentContent="this.sendMessage.content"
              :groupMembers="this.groupMemberList"
              @submit="submitMessage"
            />
            <!-- 引用消息显示区域 - 动态控制显示 -->
            <div v-if="currentQuote" class="quote-message">
              <div class="chat-quote-message">
                <div class="send-user">{{ currentQuote.senderNickname }}:</div>
                <div class="quote-content">
                  <span class="quote-text">{{ currentQuote.content }}</span>
                </div>
              </div>
              <div class="quote-remove" @click="removeQuote">
                <i class="el-icon-close"></i>
              </div>
            </div>
            <div class="send-btn-area">
              <el-button
                type="primary"
                icon="el-icon-s-promotion"
                @click="notifySend()"
                :loading="isSending"
                >发送</el-button
              >
            </div>
          </div>
        </div>
        <div v-show="!groupChatStatus">
          <span class="disband-notice-container">
            <span class="disband-notice-text">
              <span class="el-icon-warning disband-warning-icon"></span
              >&nbsp;群主已解散该群聊，禁止发送消息
            </span>
          </span>
        </div>
      </el-footer>
    </el-container>
    <voice-recorder
      :visible.sync="showVoiceRecorder"
      :max-duration="60"
      :min-duration="1"
      @voice-sent="handleVoiceSent"
    ></voice-recorder>
  </div>
</template>

<script>
import ChatContent from "./Wechat/ChatContent";
import { getToken } from "../utils/auth";
import { socket } from "../config/websocket/socket";
import Emoji from "../assets/icon/emoji.svg";
import VoiceRecorder from "./Common/VoiceRecorder";
import ChatEditor from "./editor/ChatEditor";
import service from "../utils/request";
import { createThrottle } from '@/utils/debounceThrottle';
import sendMessageMixin from "@/mixins/sendMessageMixin";
import draftMixin from "@/mixins/draftMixin";
import shortcutMixin from "@/mixins/shortcutMixin";

// 消息类型常量
const MESSAGE_TYPES = {
  TEXT: 0,
  IMAGE: 1,
  FILE: 2,
  VOICE: 6,
  QUOTE: 11,
};

// 防抖函数
function debounce(func, wait) {
  let timeout;
  return function executedFunction(...args) {
    const later = () => {
      clearTimeout(timeout);
      func(...args);
    };
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
  };
}

export default {
  components: {
    ChatContent,
    ChatEditor,
    Emoji,
    VoiceRecorder,
  },
  name: "ChatBox",
  mixins: [sendMessageMixin, draftMixin, shortcutMixin],
  data() {
    return {
      // 基础状态
      showScrollbar: false,
      emojiShow: false,
      faceList: [],
      groupChatStatus: true,
      scrolltMax: 0,
      content: "",
      getBrowString: "",
      chatType: 0,
      showVoiceRecorder: false,

      // 消息相关
      currentQuote: null,
      groupMemberList: [],
      isSending: false,
      uploadProgress: 0,

      // 消息对象
      sendMessage: {
        receiverId: "",
        content: "",
        messageType: 0,
        extInfo: "",
        isRetracted: 0,
        isRetracted: 0,
      },
      sendGroupChatMessage: {
        groupChatId: "",
        content: "",
        messageType: 0,
        extInfo: "",
        atUserIds: [],
      },

      // OSS配置
      objectData: {
        OSSAccessKeyId: "",
        policy: "",
        Signature: "",
        key: "",
        host: "",
        dir: "",
      },

      // 缓存DOM元素引用
      mainElement: null,
    };
  },

  watch: {
    'sendMessage.content'(val) {
      if (this.currentChatId) {
        this.$saveDraft(this.currentChatId, val || "");
      }
    }
  },

  computed: {
    // 当前消息对象
    currentMessage() {
      return this.chatType === 1 ? this.sendMessage : this.sendGroupChatMessage;
    },
    
    // 当前聊天ID
    currentChatId() {
      return this.$store.getters["chat/currentChatId"];
    },
  },

  methods: {
    // 处理引用消息
    handleQuoteMessage(quoteInfo) {
      this.currentQuote = quoteInfo;
      this.$nextTick(() => {
        this.$refs.chatEditor?.focus();
      });
    },

    // 移除引用消息
    removeQuote() {
      this.currentQuote = null;
    },

    // 通知发送
    notifySend() {
      this.$refs.chatEditor?.submit();
    },

    // 显示录音框
    showRecordBox() {
      this.showVoiceRecorder = !this.showVoiceRecorder;
    },

    // 处理语音发送
    handleVoiceSent(data) {
      const message = this.currentMessage;
      message.messageType = MESSAGE_TYPES.VOICE;
      message.extInfo = data;
      socket.send(message);
    },

    // 加载表情
    loadEmojis() {
      if (this.faceList.length > 0) return; // 避免重复加载

      try {
        const appData = require("../assets/mate/emojis.json");
        this.faceList = appData.map((item) => item.char);
      } catch (error) {
        console.error("加载表情失败:", error);
      }
    },

    // 获取表情
    getBrow(index) {
      const emoji = this.faceList[index];
      if (emoji) {
        this.getBrowString = emoji;
        this.content = this.content + this.getBrowString;
      }
      this.emojiShow = false;
    },

    // 提交消息 - 优化后的主方法
    async submitMessage(messageData) {
      if (this.isSending) return;
      this.isSending = true;
      this.uploadProgress = 0;
      try {
        // 处理文件上传
        const processedData = await this.processFilesBeforeSend(messageData);
        // 构建消息
        const message = this.buildMessage(processedData);

        if (!message) {
          throw new Error("消息构建失败");
        }
        
        // 使用通用发送流程（含乐观更新、服务端发送与状态更新）
        await this.$sendMessageCommon(message);

        // 重置状态
        this.resetAfterSend();
        // 清理草稿
        this.$clearDraft(this.currentChatId);
      } catch (error) {
        this.handleSendError(error);
      } finally {
        this.isSending = false;
        this.uploadProgress = 0;
      }
    },

    // 处理发送前的文件上传
    async processFilesBeforeSend(messageData) {
      const data = { ...messageData };
      // 需要上传的文件类型
      const uploadTypes = [
        MESSAGE_TYPES.IMAGE,
        MESSAGE_TYPES.FILE,
        MESSAGE_TYPES.VOICE,
      ];

      if (uploadTypes.includes(data.messageType)) {
        // 如果文件尚未上传，进行上传
        if (data.extInfo) {
          const uploadResult = await this.uploadFile(data);
          data.extInfo.mediaUrl = uploadResult.url;
          data.extInfo.mediaSize = uploadResult.size;
        }
      }

      // else if (data.type === MESSAGE_TYPES.QUOTE && this.currentQuote) {
      //   data.quote = this.currentQuote;
      // }

      return data;
    },

    // 上传文件到服务器
    async uploadFile(messageData) {
      const formData = this.createFormData(messageData);
      try {
        const response = await service({
          method: "POST",
          url: `/upload/oss`,
          data: formData,
          onUploadProgress: this.handleUploadProgress,
        });
        return {
          url: response.data,
          size: messageData.extInfo.size,
          name: messageData.extInfo.name,
        };
      } catch (error) {
        throw new Error(`文件上传失败: ${error.message || "网络错误"}`);
      }
    },

    // 创建FormData
    createFormData(messageData) {
      const formData = new FormData();
      formData.append("file", messageData.extInfo.file);
      formData.append("type", messageData.messageType);
      if (
        messageData.type === MESSAGE_TYPES.VOICE &&
        messageData.extInfo.duration
      ) {
        formData.append("duration", messageData.extInfo.duration);
      }
      return formData;
    },

    // 处理上传进度
    handleUploadProgress(progressEvent) {
      this.uploadProgress = Math.round(
        (progressEvent.loaded / progressEvent.total) * 100
      );
    },

    // 获取上传端点
    getUploadEndpoint(type) {
      const endpointMap = {
        [MESSAGE_TYPES.IMAGE]: "image",
        [MESSAGE_TYPES.FILE]: "file",
        [MESSAGE_TYPES.VOICE]: "voice",
      };
      return endpointMap[type] || "file";
    },

    // 构建消息对象
    buildMessage(data) {
      const message = { ...this.currentMessage };
      // 根据消息类型设置字段
      const messageBuilders = {
        [MESSAGE_TYPES.TEXT]: () => {
          message.content = data.content;
          message.messageType = MESSAGE_TYPES.TEXT;
          message.atUserIds = data.atUserIds || [];
        },
        [MESSAGE_TYPES.IMAGE]: () => {
          message.messageType = MESSAGE_TYPES.IMAGE;
          message.extInfo = JSON.stringify(data.extInfo);
        },
        [MESSAGE_TYPES.FILE]: () => {
          message.messageType = MESSAGE_TYPES.FILE;
          message.extInfo = JSON.stringify(data.extInfo);
        },
        [MESSAGE_TYPES.VOICE]: () => {
          message.messageType = MESSAGE_TYPES.VOICE;
          message.extInfo = JSON.stringify(data.extInfo);
        },
        [MESSAGE_TYPES.QUOTE]: () => {
          message.content = data.content;
          message.messageType = MESSAGE_TYPES.QUOTE;
          message.extInfo = JSON.stringify(data.quote || this.currentQuote);
          message.atUserIds = data.atUserIds || [];
        },
      };

      const builder = messageBuilders[data.messageType];
      if (!builder) {
        this.$notify({
          type: "error",
          title: "发送失败",
          message: "不支持的消息类型",
        });
        return null;
      }
      builder();
      // 处理引用消息
      if (this.currentQuote) {
        message.extInfo = JSON.stringify(this.currentQuote);
        message.messageType = MESSAGE_TYPES.QUOTE;
      }
      return message;
    },

    // 获取消息预览文本
    getMessagePreview(message) {
      switch (message.messageType) {
        case 'image':
          return '[图片]';
        case 'voice':
          return '[语音]';
        case 'file':
          return '[文件]';
        case 'video':
          return '[视频]';
        case 'location':
          return '[位置]';
        default:
          return message.content || '[消息]';
      }
    },

    // 发送逻辑已由 mixin 接管
    // 创建乐观消息
    createOptimisticMessage(message) {
      const userInfo = this.$store.getters.userLogin;
      if (!userInfo) {
        console.warn('用户信息未加载，无法创建乐观消息');
        return null;
      }
      const tempId = `temp_${Date.now()}_${Math.random()}`;
      return {
        id: tempId,
        content: message.content,
        mediaUrl: message.mediaUrl,
        mediaName: message.mediaName,
        mediaSize: message.mediaSize,
        duration: message.duration,
        messageType: message.extend,
        createTime: new Date().toISOString(),
        isMyselfMsg: true,
        myUserId: userInfo.id,
        myNickName: userInfo.nickName,
        myAvatar: userInfo.avatar,
        othersUserId: message.receiverId || message.groupChatId,
        isSendSuccessfully: 0, // 0: 发送中, 1: 成功, 2: 失败
        isRead: 0,
        tempId: tempId, // 用于后续匹配真实消息
        quoteId: message.quoteId,
        quoteData: message.quoteData,
        atUserIds: message.atUserIds || [],
      };
    },

    // 添加消息到UI
    addMessageToUI(message) {
      this.$refs.weChatContent?.addOptimisticMessage(message);
    },

    // 更新消息状态
    updateMessageStatus(tempId, status) {
      this.$refs.weChatContent?.updateMessageStatus(tempId, status);
    },

    // 重置发送后状态
    resetAfterSend() {
      this.currentQuote = null;
      this.$refs.chatEditor?.clear();
    },

    // 处理发送错误
    handleSendError(error) {
      console.error("消息发送错误:", error);
      this.$notify({
        type: "error",
        title: "发送失败",
        message: error.message || "消息发送失败，请重试",
      });
    },

    // 聊天框初始化
    chatBox(data) {
      console.log('ChatBox chatBox called with data:', data);
      this.groupChatStatus = true;
      this.content = "";
      this.scrolltMax = 0;

      // 使用新的状态管理设置当前聊天
      this.$store.dispatch("chat/setCurrentChat", data);

      if (data.type === 1) {
        // 单聊
        this.sendMessage.receiverId = data.friendshipId;
        this.chatType = 1;
        console.log('ChatBox chatBox - calling userChatMessages with receiverId:', this.sendMessage.receiverId);
        this.$refs.weChatContent?.userChatMessages(this.sendMessage.receiverId);
      } else if (data.type === 0) {
        // 群聊
        this.sendGroupChatMessage.groupChatId = data.friendshipId;
        this.chatType = 0;
        this.getGroupChatStatus(this.sendGroupChatMessage.groupChatId);
        this.getGroupMembers(data.friendshipId);
        this.$refs.weChatContent?.userGroupChatMessages(
          this.sendGroupChatMessage.groupChatId
        );
      }

      this.$refs.chatEditor?.focus();

      // 恢复草稿
      const draft = this.$loadDraft(this.currentChatId);
      if (typeof draft === 'string') {
        this.sendMessage.content = draft;
      }
    },

    // OSS上传验证
    oss_upload(file) {
      const isJPG = file.type === "image/jpeg";
      if (!isJPG) {
        this.$notify({
          title: "上传图片",
          type: "error",
          message: "上传头像图片只能是 JPG 格式!",
        });
      }
      return isJPG;
    },

    // 获取群聊状态
    getGroupChatStatus(groupChatId) {
      service({
        method: "get",
        url: "/group_chat/groupChatStatus",
        params: { groupChatId },
      })
        .then((res) => {
          if (res?.code === 200) {
            this.groupChatStatus = res.data;
          }
        })
        .catch((error) => {
          console.error("获取群聊状态失败:", error);
        });
    },

    // 处理头像上传成功
    handleAvatarSuccess(res, file) {
      this.sendMessage.content = res.message;
      this.sendMessage.extend = 1;
      socket.send(this.sendMessage);
      this.sendMessage.content = "";
      this.sendMessage.extend = 0;
    },

    // 处理滚动 - 使用节流优化
    handleScroll() {
      if (!this.mainElement) return;

      const scrollHeight = this.mainElement.scrollTop;
      const scrollHeightMax = this.mainElement.scrollHeight;

      if (this.scrolltMax === 0) {
        this.scrolltMax = scrollHeightMax;
      }

      if (scrollHeight === 0) {
        this.$refs.weChatContent?.lazyUserChatMessages();
      }
    },

    // 定位视图
    positionView(index) {
      if (!this.mainElement) return;

      const scrollHeight = this.scrolltMax + this.scrolltMax * index;
      this.mainElement.scrollTop = scrollHeight - this.scrolltMax;
      this.scrolltMax = 0;
    },

    // 重新编辑
    reEdit(content) {
      if (this.$refs.chatEditor) {
        this.$refs.chatEditor.content = content;
      }
    },

    // 群聊通知
    groupChatNotify(event) {
      const params = event.detail.data;
      switch (params.message) {
        case 1:
          if (
            this.chatType === 0 &&
            this.sendGroupChatMessage.groupChatId.toString() ===
              params.data.toString()
          ) {
            this.groupChatStatus = false;
          }
          break;
        case 2:
          break;
        default:
          break;
      }
    },

    // 获取群成员
    getGroupMembers(groupId) {
      service({
        method: "get",
        url: "/group_chat/member",
        params: { chatGroupId: groupId },
      })
        .then((res) => {
          this.loading = false;
          this.groupMemberList = [...this.groupMemberList, ...res.data];
          this.total = res.total;
        })
        .catch((error) => {
          console.error("获取群成员失败:", error);
          this.loading = false;
        });
    },
  },

  created() {
    // 组件创建时的初始化
  },

  mounted() {
    this.$nextTick(() => {
      // 缓存DOM元素引用
      this.mainElement = this.$refs.mainContainer;
      
      // 创建节流版本的滚动处理函数
      this.throttledHandleScroll = createThrottle(this.handleScroll, 100);
      
      if (this.mainElement && this.mainElement.addEventListener) {
        this.mainElement.addEventListener("scroll", this.throttledHandleScroll);
      }
    });

    // 添加全局事件监听
    window.addEventListener("disbandGroupChat", this.groupChatNotify);

    // 绑定快捷键事件触发
    this.$on && this.$on('shortcut-send', this.notifySend);
    this.$on && this.$on('shortcut-escape', this.removeQuote);
  },

  beforeDestroy() {
    // 清理事件监听器
    if (this.mainElement && this.mainElement.removeEventListener) {
      this.mainElement.removeEventListener("scroll", this.throttledHandleScroll);
      this.mainElement = null;
    }
    
    // 清理节流方法
    if (this.throttledHandleScroll && this.throttledHandleScroll.cancel) {
      this.throttledHandleScroll.cancel();
    }
    
    window.removeEventListener("disbandGroupChat", this.groupChatNotify);

    // 解绑快捷键事件
    this.$off && this.$off('shortcut-send', this.notifySend);
    this.$off && this.$off('shortcut-escape', this.removeQuote);
    
    // 清理数据引用，防止内存泄漏
    this.sendMessage = {};
    this.sendGroupChatMessage = {};
    this.objectData = {};
    this.groupMemberList = [];
    this.currentQuote = null;
    
    // 清理Vuex相关引用
    this.$store = null;
  },
};
</script>

<style scoped>
.CB {
  width: 100%;
  height: 100%;
  overflow: hidden;
  box-sizing: border-box;
}

::v-deep .el-footer {
  width: 100%;
  color: #333;
  height: 270px;
  padding: 30px 20px;
}

::v-deep .el-main {
  color: #333;
  overflow-y: auto;
  height: 100%;
  flex: 1;
  display: flex;
  flex-direction: column;
}

::v-deep .el-textarea__inner {
  resize: none;
}

::v-deep .el-main::-webkit-scrollbar-track {
  display: none;
}

.el-main::-webkit-scrollbar {
  width: 5px;
}

.el-main::-webkit-scrollbar-track {
  background: #ffffff;
}

.el-main::-webkit-scrollbar-thumb {
  background: #c9c9c9;
  border-radius: 5px;
}

::v-deep .el-textarea .el-input__count {
  display: none;
}

.submit-btn {
  margin: 0 15px 10px 0;
  float: right;
}

.el-main .overScrollbar {
  overflow-y: auto;
}

.el-main .leaveScrollbar {
  overflow-y: hidden;
}

::v-deep .la.el-button {
  padding: 10px 18px;
}

.chat-tool-bar {
  display: flex;
  position: relative;
  width: 100%;
  height: 36px;
  text-align: left;
  box-sizing: border-box;
  border-top: var(--im-border);
  padding: 4px 2px 2px 8px;
  align-items: center;
}

.chat-tool-bar > div {
  font-size: 22px;
  cursor: pointer;
  line-height: 30px;
  margin-left: 15px;
  height: 30px;
  text-align: center;
  border-radius: 2px;
  color: #999;
  transition: 0.3s;
}

.send-content-area {
  position: relative;
  display: flex;
  flex-direction: column;
  height: 100%;
  background-color: white !important;
}

.send-btn-area {
  padding: 10px;
  position: absolute;
  bottom: 4px;
  right: 6px;
}

.quote-message {
  position: absolute;
  bottom: 10px;
  left: 10px;
  font-size: 14px;
  max-width: 80%;
  border-radius: 5px;
}

.chat-quote-message {
  background: #f3f3f3;
  padding: 5px;
  display: inline-flex;
  align-items: center;
  border-radius: 8px;
  font-size: 12px;
  color: #888;
}

.chat-quote-message .send-user {
  margin-right: 10px;
  font-weight: 600;
  white-space: nowrap;
}

.chat-quote-message .quote-content .quote-text {
  display: inline-block;
  text-align: left;
  white-space: pre-wrap;
  word-break: break-all;
}

.chat-quote-message .quote-content .quote-file {
  display: flex;
  flex-wrap: nowrap;
  flex-direction: row;
  align-items: center;
  cursor: pointer;
  padding: 2px 15px;
  background: #fff;
  box-shadow: #888;
  border-radius: 4px;
}

.send-content-area .quote-message .quote-remove {
  display: none;
  position: absolute;
  top: -8px;
  right: -8px;
  width: 20px;
  height: 20px;
  line-height: 20px;
  font-size: 14px;
  color: #fff;
  border-radius: 50%;
  background: #aaa;
  cursor: pointer;
}

.quote-message:hover .quote-remove {
  display: block;
}

.quote-remove:hover {
  background: #777;
}

/* 提取的内联样式 */
.chat-container-height {
  height: 100%;
  display: flex;
  flex-direction: column;
}

.disband-notice-container {
  border-top: 1px solid #cccccc;
  display: flex;
  justify-content: center;
  line-height: 150px;
  cursor: default;
}

.disband-notice-text {
  font-size: 18px;
  color: #999999;
}

.disband-warning-icon {
  color: #a30000;
}
</style>